package com.efrei.schoolmanager.views;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.efrei.schoolmanager.controlers.ControleurClasse;
import com.efrei.schoolmanager.model.ModeleListeClasses;
import com.efrei.schoolmanager.model.obj.Classe;
import com.efrei.schoolmanager.views.components.CustomButton;

/**
 * Vue de listage des classes de l'application
 * 
 */
public class VueListerClasse extends JPanel {
	private static final long serialVersionUID = -1010565036068763522L;

	// Proprietaire de cette dialog(objectif: rendre modale la jdialog)
	private final VueGenerale proprio;

	private final ControleurClasse controleur;

	// JPanels
	private JPanel tablePanel, titlePanel, buttonPanel, button2Panel;

	// JTable
	private JTable infoClassesTable;

	// JButtons
	private CustomButton modifierClasseButton, ajouterClasseButton,
			editerMatieresClasseButton, validerModificationButton,
			editerElevesClasseButton;

	// JLabels
	private JLabel listeClasseLabel;

	private ModeleListeClasses modeleClasse;

	private final VueListerClasse vueActuelle;

	public VueListerClasse(final VueGenerale proprio,
			final ControleurClasse controleur) {
		this.vueActuelle = this;
		this.proprio = proprio;

		this.controleur = controleur;

		new Thread(new Runnable() {
			@Override
			public void run() {
				boolean error = false;
				// Chargement de l'écran
				try {
					initLabel();
					initPanels();
					initButtons();
					initTable();
					remplirTitlePanel();
					remplirTablePanel();
					remplirButtonPanel();
					configurerVue();
				} catch (final Exception e) {
					// En cas d'erreur, on efface tout
					error = true;
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							proprio.displayError(e);
							proprio.removePanel();
							proprio.stopBarreChargement();
						}
					});
				}
				if (!error)
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							proprio.stopBarreChargement();
						}
					});
			}
		}).start();
		proprio.startBarreChargement();

	}

	/**
	 * Configurer contenu de la vue
	 */
	private void configurerVue() {
		// Gestionnaire de positionnement
		BoxLayout layout = new BoxLayout(this, BoxLayout.PAGE_AXIS);
		Box box = Box.createVerticalBox();
		box.add(titlePanel);
		box.add(tablePanel);
		box.add(buttonPanel);
		box.add(button2Panel);
		this.add(box);
		setLayout(layout);
	}

	private void initButtons() {
		// Ajout de classe
		ajouterClasseButton = new CustomButton("Ajouter une classe");
		ajouterClasseButton.addActionListener(new AjouterClasseListener());
		// Modification de classe
		modifierClasseButton = new CustomButton("Modifier la classe");
		modifierClasseButton.addActionListener(new ModifierClasseListener());
		modifierClasseButton.setEnabled(false);
		// Editer matieres d'une classe
		editerMatieresClasseButton = new CustomButton("Editer les matieres");
		editerMatieresClasseButton
				.addActionListener(new EditerMatieresListener());
		editerMatieresClasseButton.setEnabled(false);
		// Editer eleves d'une classe
		editerElevesClasseButton = new CustomButton("Editer les eleves");
		editerElevesClasseButton.addActionListener(new EditerElevesListener());
		editerElevesClasseButton.setEnabled(false);
		// Validation des modifications
		validerModificationButton = new CustomButton(
				"Valider les modifications");
		validerModificationButton
				.addActionListener(new ValiderModificationListener());
	}

	private void remplirTitlePanel() {
		titlePanel = new JPanel();
		titlePanel.add(listeClasseLabel);
	}

	private void remplirTablePanel() {
		tablePanel = new JPanel(new BorderLayout());
		tablePanel.add(infoClassesTable.getTableHeader(), BorderLayout.NORTH);
		tablePanel.add(new JScrollPane(infoClassesTable), BorderLayout.CENTER);
	}

	private void remplirButtonPanel() {
		buttonPanel.add(ajouterClasseButton);
		buttonPanel.add(modifierClasseButton);
		buttonPanel.add(editerMatieresClasseButton);
		buttonPanel.add(editerElevesClasseButton);

		button2Panel.add(validerModificationButton);
	}

	private void initTable() {
		modeleClasse = new ModeleListeClasses(controleur);
		infoClassesTable = new JTable(modeleClasse);
		infoClassesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		ListSelectionModel listSelectionModel = infoClassesTable
				.getSelectionModel();
		listSelectionModel
				.addListSelectionListener(new ListeClasseTableListSelectionListener());
	}

	private void initLabel() {
		listeClasseLabel = new JLabel("Liste des classes");
		listeClasseLabel.setFont(new Font("Arial", Font.BOLD, 20));
	}

	private void initPanels() {
		tablePanel = new JPanel(new FlowLayout());
		titlePanel = new JPanel(new FlowLayout());
		buttonPanel = new JPanel(new FlowLayout());
		button2Panel = new JPanel(new FlowLayout());
	}

	public VueGenerale getFrame() {
		return proprio;
	}

	public ControleurClasse getControleur() {
		return controleur;
	}

	/* Listeners */
	class AjouterClasseListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			DialogAjouterClasse dac = new DialogAjouterClasse(proprio,
					controleur);
			if (dac.showDialog()) {
				// On met a jour le tableau avec la nouvelle entrée
				int size = controleur.getClasses().size();
				modeleClasse.fireTableRowsInserted(size, size);
			}
		}

	}

	class ModifierClasseListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (infoClassesTable.getSelectedRow() >= 0) {
				Classe classeSelectionee = modeleClasse
						.getClasse(infoClassesTable.getSelectedRow());
				DialogModifierClasse dmc = new DialogModifierClasse(proprio,
						classeSelectionee);
				dmc.showDialog();
				modeleClasse.fireTableRowsUpdated(
						infoClassesTable.getSelectedRow(),
						infoClassesTable.getSelectedRow());
			}
		}
	}

	class EditerMatieresListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (infoClassesTable.getSelectedRow() >= 0) {
				Classe classeSelectionee = modeleClasse
						.getClasse(infoClassesTable.getSelectedRow());
				controleur.setCurrentClasse(classeSelectionee);
				new VueEditerMatieres(vueActuelle, controleur);
			}
		}
	}

	class EditerElevesListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (infoClassesTable.getSelectedRow() >= 0) {
				Classe classeSelectionee = modeleClasse
						.getClasse(infoClassesTable.getSelectedRow());
				controleur.setCurrentClasse(classeSelectionee);
				new VueEditerElevesClasse(vueActuelle, controleur);
			}
		}
	}

	class ListeClasseTableListSelectionListener implements
			ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent e) {
			if (infoClassesTable.getSelectedRow() != -1) {
				modifierClasseButton.setEnabled(true);
				editerMatieresClasseButton.setEnabled(true);
				editerElevesClasseButton.setEnabled(true);
			} else {
				modifierClasseButton.setEnabled(false);
				editerMatieresClasseButton.setEnabled(false);
				editerElevesClasseButton.setEnabled(false);
			}
		}

	}

	class ValiderModificationListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			new Thread(new ControlerValidator(controleur, proprio)).start();
			// Pendant ce temps, chargement
			vueActuelle.getFrame().startBarreChargement();
		}
	}

}
